"""
将一个复杂对象的构建与它的表示分离，使得同样的构造过程可以创建不同的表示。

和工厂模式不一样，工厂模式是直接返回一个产品（或工厂），输入输出，相当直接，建造者模式就要辛苦一点，需要指挥者指挥建造者工作之后，才能获得产品，所以建造者模式需要指挥者和建造者两个角色

角色：
    抽象建造者（Builder）
    具体建造者（Concrete Builder）
    指挥者（Director）
    产品（Product）

其实就是：
0、创建一个产品信息
1、创建一个抽象的建造者，里面有脸-身体-手-腿
2、实现具体建造者，把对应的参数给产品信息（通过init得到产品对象，把具体的信息直接给产品对象）
3、创建指挥者，控制角色组装顺序，并返回具体建造者对象
"""

from abc import abstractmethod, ABCMeta


class Player:
    """产品信息"""

    def __init__(self, face=None, body=None, arm=None, leg=None):
        self.face = face
        self.body = body
        self.arm = arm
        self.leg = leg

    def __str__(self):
        return "游戏角色信息：{} -- {} -- {} -- {}".format(self.face, self.body, self.arm, self.leg)


class PlayerBuilder(metaclass=ABCMeta):
    """抽象建造者，脸-身体-手-腿"""

    @abstractmethod
    def build_face(self):
        pass

    @abstractmethod
    def build_body(self):
        pass

    @abstractmethod
    def build_arm(self):
        pass

    @abstractmethod
    def build_leg(self):
        pass


class ConcreteBuilder(PlayerBuilder):
    """具体建造者"""

    def __init__(self):
        self.player = Player()  # 把得到的信息，给产品详细

    def build_face(self):
        self.player.face = "人脸"

    def build_body(self):
        self.player.body = "猪身体"

    def build_arm(self):
        self.player.arm = "大白手"

    def build_leg(self):
        self.player.leg = "细腿"


class PlayerDirector:
    """指挥者，控制组装顺序"""

    def build_player(self, builder):
        builder.build_body()
        builder.build_face()
        builder.build_arm()
        builder.build_leg()
        return builder.player


builder = ConcreteBuilder()  # 具体建造者
director = PlayerDirector()  # 指挥者
p = director.build_player(builder)
print(p)
